package win.demonlegion.util;

import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;

/**
 * AES对称加密工具类
 */
@Slf4j
public class AesUtils {
    private static final String ALGORITHM = "AES"; // 加密算法
    private static final String AES_TRANSFORMATION = "AES/CBC/PKCS5Padding"; // 填充模式
    // 编码
    public static final String ENCODING = "UTF-8";
    // 默认的加密算法
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
    /**
     * AES加密
     *
     * @param content 加密内容
     * @param aesKey  加密Key
     * @param aesIv   偏移量
     * @return String
     * @throws Exception
     */
    public static String encrypt(String content, String aesKey, String aesIv) {
        try {
            Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(aesIv.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(aesKey.getBytes(), ALGORITHM), iv);

            byte[] encryptBytes = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
            return Base64Util.toBase64(encryptBytes);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * AES解密
     *
     * @param content 解密内容
     * @param aesKey  加密Key
     * @param aesIv   偏移量
     * @return String
     */
    public static String decrypt(String content, String aesKey, String aesIv) {
        try {
            Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(aesIv.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(aesKey.getBytes(), ALGORITHM), iv);
            byte[] cleanBytes = cipher.doFinal(Base64Util.parseBase64(content.getBytes(StandardCharsets.UTF_8)));
            return new String(cleanBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 解密
     * @param secret
     * @param iv
     * @param content
     * @return
     */
    public static String decode(String secret, String iv, String content) {
        try {
            byte[] secretKeyBytes = secret.getBytes();
            SecretKey secretKey = new SecretKeySpec(secretKeyBytes, ALGORITHM);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
            return Base64Util.toBase64(content);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }
}
